package fidel.permission.controller.interceptor;

import java.util.Objects;
import java.util.Set;

import javax.servlet.RequestDispatcher;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import fidel.permission.po.ActiveUser;
import fidel.permission.util.ResourcesUtil;

/**
 * 
 * 身份认证拦截器
 * 
 * @author fidel
 * @date 2021年5月
 * @version 1.0
 */
public class AuthenticationInterceptor implements HandlerInterceptor {

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
        throws Exception {
        // 获取去除请求的上下文路径前缀的uri路径
        String servletPath = request.getServletPath(), loginPath = "/login.action", indexPath = "/index.action";
        RequestDispatcher dispatcher = request.getRequestDispatcher("/WEB-INF/page/login.jsp");
        HttpSession session = request.getSession();
        ActiveUser activeUser = (ActiveUser) session.getAttribute("activeUser");
        // 获取可匿名访问的uri集合
        Set<String> set = ResourcesUtil.getKeys("anonymous");
        // 如果uri集合中包含path
        if (set.contains(servletPath)) {
            // 如果当前路径与loginPath相等
            if (servletPath.equals(loginPath)) {
                if (Objects.nonNull(activeUser)) {
                    // 重定向至主页
                    response.sendRedirect(request.getContextPath().concat(indexPath));
                    return false;
                }
                // 如果请求方式为get
                if (request.getMethod().equals("GET")) {
                    // 转发请求至登录页面
                    dispatcher.forward(request, response);
                    return false;
                }
                // 请求方式为post，且会话未存储ActiveUser实例
            }
            // 请求的地址是其他可匿名访问的地址
            return true;
        }
        // 对于不可匿名访问的地址同样选择放行，因为可以交由授权拦截器处理
        return true;
    }

    // 在执行handler返回modelAndView之前来执行
    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
        ModelAndView modelAndView) throws Exception {
    }

    /*执行handler之后执行此方法*/
    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
        throws Exception {
    }

}
